package cn.itcast.nems.studentrecord.service;

import cn.itcast.nems.discount.dto.DiscountSummaryDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author liyong
 * create: 2023-11-15 11:47:09
 **/
public class DiscountCalculator {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final List<DiscountSummaryDTO> discounts;

    /**
     * key: discountId, value:discountAmount
     */
    private Map<Integer, Integer> discountAmounts;

    public DiscountCalculator(List<DiscountSummaryDTO> discounts) {
        this.discounts = discounts;
    }

    /**
     * 计算优惠总金额
     *
     * @param originPrice 原始价格
     * @param amountDue   应缴金额(如果为空，则使用原始价格)
     * @return 优惠总额
     */
    public int calculate(int originPrice, Integer amountDue) {
        amountDue = amountDue == null ? originPrice : amountDue;
        int limitAmount = amountDue;
        this.discountAmounts = new LinkedHashMap<>();
        int result = 0;
        for (DiscountSummaryDTO discount : discounts) {
            final int da = this.calDiscount(originPrice, discount, limitAmount);
            result += da;
            this.discountAmounts.put(discount.getId(), da);
            limitAmount -= da;
        }
        return result < amountDue ? result : amountDue;
    }

    /**
     * 每个优惠优惠的金额（仅在调用完calculate后才有值）
     *
     * @return key: 优惠ID, value: 优惠ID对应的优惠金额
     */
    public Map<Integer, Integer> getDiscountAmounts() {
        return discountAmounts;
    }

    /**
     * 计算某项优惠的金额
     *
     * @param originPrice 原始价格
     * @param discountId  优惠ID
     * @param amountDue   应缴金额(如果为空，则使用原始价格)
     * @return 优惠金额
     */
    public int calculateOne(int originPrice, int discountId, Integer amountDue) {
        int discount = this.discounts
                .stream()
                .filter(d -> d.getId() == discountId)
                .findAny()
                .map(d -> this.calDiscount(originPrice, d, amountDue))
                .orElseGet(() -> {
                    logger.warn("没有找到匹配的优惠，优惠ID: {}", discountId);
                    return 0;
                });
        return discount < amountDue ? discount : amountDue;
    }

    private int calDiscount(int originPrice, DiscountSummaryDTO d, Integer amountDue) {
        int result;
        if (d.getType().intValue() == 0) {
            result = d.getAmount().multiply(BigDecimal.valueOf(100)).intValue();
        } else {
            result = BigDecimal.valueOf(d.getRate()).multiply(BigDecimal.valueOf(originPrice)).intValue();
        }
        amountDue = amountDue == null ? originPrice : amountDue;
        result = result < amountDue ? result : amountDue;
        return result;
    }
}
